<!-- eslint-disable vue/multi-word-component-names -->
<!--
* Copyright (c) 2022 Beijing Jiaotong University
* PhotLab is licensed under [Open Source License].
* You can use this software according to the terms and conditions of the [Open Source License].
* You may obtain a copy of [Open Source License] at: [https://open.source.license/]
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the [Open Source License] for more details.
*
* Author: Zhenjie Wei
* Created: Jul. 20, 2023
* Supported by: National Key Research and Development Program of China
-->

<template>
    <div class="sceneWrapper" ref="sceneWrapperRef">
        <canvas
            id="scene"
            @drop="handleDrop"
            @mousemove="workspaceOnMove"
            @dragover="workspaceOnDragMove"
            @mouseleave="workspaceOnLeave"
            @click="onNodeClick"
            @click.right="showContextMenu"
        ></canvas>
    </div>
</template>

<script setup lang="ts">
import { ipcRenderer } from 'electron'
import { onMounted, reactive, ref, getCurrentInstance } from 'vue'
import { Point, Rect, Size } from '@/common/logic/common/types2D'
import ContextMenu from '../../MenuContext'
import Designer from './designer'
import { useStore } from 'vuex'
import { graphManager } from '@/services/phot_client/graph'
import { deviceManager } from '@/services/phot_client/device'
import { posix } from 'upath'
import { engineManager } from '@/services/phot_client/engine'
import { PhotTaskStatus } from '@/common/types/phot_types'
import Loading from '@/components/Loading'

const { proxy } = getCurrentInstance() as any

const store = useStore()

const sceneWrapperRef = ref(null)

const mainRef = reactive({
    dragComponent: {},
    selectedCompo: {}
}) as any

let designer: Designer

const emit = defineEmits({
    onNodeClickHandle: (val: any) => {},
})

onMounted(() => {
    const scene = document.getElementById('scene') as HTMLCanvasElement

    if (!scene) {
        console.error('scene not found, please check if the element is correctly mounted')
        return
    }

    designer = new Designer(scene)

    const wrapper = sceneWrapperRef.value! as HTMLElement
    scene.style.width = wrapper.clientWidth + 'px'
    scene.style.height = wrapper.clientHeight + 'px'

    window.addEventListener('resize', () => {
        scene.style.width = wrapper.clientWidth + 'px'
        scene.style.height = wrapper.clientHeight + 'px'
    })
})

const handleDrop = async (event: DragEvent) => {
    event.preventDefault()
    // 获取传输的数据，这里使用 "text/plain" 格式
    if (!graphManager.photGraph) {
        return proxy.$toast({
            value: '未检测到仿真工程，请创建后再尝试!',
            type: "error"
        })
    }
    const data: any = event?.dataTransfer?.getData('text/plain')
    const recv = JSON.parse(data)
    mainRef.dragComponent = recv.comp
    console.log('dragComponent: ', mainRef.dragComponent)
    const pos = new Point(store.state.coordinate[0], store.state.coordinate[1])
    console.log('pos', pos.desc)
    console.log('recv', recv)
    const success = await graphManager.addComponentFromLibrary(recv.comp.component.path, pos)
    if (success) {
        await proxy.$parent.$refs.ComponentContentRef.init()
    } else {
        proxy.$toast({
            value: '添加组件失败！',
            type: "error"
        })
    }
}

const workspaceOnMove = (event: MouseEvent) => {
    event.preventDefault()
    const core = designer.core
    const pos = new Point(event.offsetX, event.offsetY)
    store.dispatch('setCoordinate', [
        core.pos2crd(pos).floor().x,
        core.pos2crd(pos).floor().y,
    ])
}

const workspaceOnDragMove = (event: DragEvent) => {
    event.preventDefault()
    const core = designer.core
    const pos = new Point(event.offsetX, event.offsetY)
    store.dispatch('setCoordinate', [
        core.pos2crd(pos).floor().x,
        core.pos2crd(pos).floor().y,
    ])
}

const workspaceOnLeave = (event: MouseEvent) => {
    store.dispatch('setCoordinate', [0, 0])
}

const onNodeClick = async () => {
    // console.log(graphManager.logicCore)
    if (
        graphManager.logicCore &&
        graphManager.logicCore.recentSelectedLogicObject
    ) {
        // console.log(graphManager.photGraph)
        const component = await graphManager.getComponent(
            graphManager.logicCore.recentSelectedLogicObject.id
        )
        mainRef.selectedCompo = component
        console.log(mainRef.selectedCompo)
        proxy.$parent.$refs.ComponentContentRef.chooseCompo(component)
    }
}

const showContextMenu = async (e: any) => {
    console.log(graphManager.logicCore)
    if (
        graphManager.logicCore &&
        graphManager.logicCore.recentSelectedLogicObject
    ) {
        // console.log(graphManager.photGraph)
        const menuList = [
            {
                label: '编辑参数',
                type: 'edit',
                fn: () => {
                    proxy.$parent.$refs.ParameterEditorRef.init()
                }
            },
            // {
            //     label: '删除',
            //     type: 'delete',
            //     fn: () => {
            //         console.log('删除组件:',  graphManager.logicCore?.recentSelectedLogicObject)
            //     }
            // },
            {
                label: '输出结果',
                type: 'output',
                fn: async () => {
                    const taskStatus = await engineManager.getTaskStatus(graphManager.photGraph.graphId!)
                    console.log(taskStatus)
                    proxy.$loading.open('正在输出结果...')
                    // if (mainRef.selectedCompo.isAnalyzer) {
                        try {
                            if (taskStatus === PhotTaskStatus.TASK_ACCOMPLISHED) {
                                const output = mainRef.selectedCompo.isAnalyzer ? await engineManager.getAnalyzerOutput(mainRef.selectedCompo.componentId) : await engineManager.getComponentOutput(mainRef.selectedCompo.componentId)
                                console.log(output)
                                proxy.$toast({
                                    value: '输出成功！',
                                    type: 'success'
                                })
                                await ipcRenderer.send('control', 'new-win', 'PhotAnalyze')
                                await ipcRenderer.send('sendData', 'PhotAnalyze', 'output', {componentOutputs: output, graphId: graphManager.photGraph.graphId, graph: graphManager.photGraph, isAnalyzer: mainRef.selectedCompo.isAnalyzer})
                            } else {
                                proxy.$toast({
                                    value: '未完成任务，无法输出结果！',
                                    type: 'error'
                                })
                            }
                            proxy.$loading.close()
                        } catch (err) {
                            proxy.$loading.close()
                            proxy.$toast({
                                value: err,
                                type: 'error'
                            })
                        }
                    // }
                }
            }
        ]
        e.preventDefault()
        ContextMenu(e, menuList)
    } else {
        const menuList = [
            {
                label: '编辑系统参数',
                type: 'edit',
                fn: () => {
                    proxy.$parent.$refs.EnvironmentVariablesRef.init()
                }
            }
        ]
        e.preventDefault()
        ContextMenu(e, menuList)
    }
}
</script>

<style scoped>
.sceneWrapper {
    position: relative;
    width: 100%;
    height: 100%;
}
#scene {
    outline: none;
}
</style>
